package formula.one.urjc.escuderia;
import java.io.Serializable;
import java.util.ArrayList;

import formula.one.urjc.circuito.Circuito;
import formula.one.urjc.piloto.Piloto;
import formula.one.urjc.piloto.PilotoOficial;
import formula.one.urjc.piloto.PilotoProbador;

/**
 *
 * @author Javier Aparicio García
 */
public class Escuderia implements Serializable{
	//propiedades constantes
	static final int PILOTO_OFICIAL=0;
	static final int PILOTO_PROBADOR=1;
	
	//propiedades obligatorias para dar de alta una escudería
	private String propietario;
	private String nombre;
	private String pais;
	private int anyoFundacion;
	private double presupuesto;
	private int puntos;
	private String directivos;
	private ArrayList<Piloto> pilotosOficiales;
	private ArrayList<Piloto> pilotosProbadores;
	
	private Coche[] coches;
	private ArrayList<PilotoCoche> listaCompetidores;
	
	//Único constructor de  Alta 
	public Escuderia(String propietario, String nombre, String pais,
			int anyoFundacion, double presupuesto, String directivos) {
		
		this.propietario = propietario;
		this.nombre = nombre;
		this.pais = pais;
		this.anyoFundacion = anyoFundacion;
		this.presupuesto = presupuesto;
		puntos=0;
		this.directivos = directivos;
                listaCompetidores=new ArrayList<PilotoCoche>();
                this.pilotosOficiales=new ArrayList<Piloto>();
                this.pilotosProbadores=new ArrayList<Piloto>();
                coches=new Coche[2];
                listaCompetidores=new ArrayList<PilotoCoche>();
	}

	public String getPropietario() {
		return propietario;
	}

	public String getNombre() {
		return nombre;
	}

	public String getPais() {
		return pais;
	}

	public int getAnyoFundacion() {
		return anyoFundacion;
	}

	public double getPresupuesto() {
		return presupuesto;
	}

	public int getPuntos() {
		return puntos;
	}

	public String getDirectivos() {
		return directivos;
	}

	public ArrayList<Piloto> getPilotosOficiales() {
		return pilotosOficiales;
	}

	public ArrayList<Piloto> getPilotosProbadores() {
		return pilotosProbadores;
	}

	public Coche[] getCoches() {
		return coches;
	}

	public ArrayList<PilotoCoche> getListaCompetidores() {
            return listaCompetidores;
	}

	public void setPropietario(String propietario) {
		this.propietario = propietario;
	}

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	public void setPais(String pais) {
		this.pais = pais;
	}

	public void setAnyoFundacion(int anyoFundacion) {
		this.anyoFundacion = anyoFundacion;
	}

	public void setPresupuesto(double presupuesto) {
		this.presupuesto = presupuesto;
	}

	public void setPuntos(int puntos) {
		this.puntos = puntos;
	}

	public void setDirectivos(String directivos) {
		this.directivos = directivos;
	}

	public void setPilotosOficiales(ArrayList<Piloto> pilotosOficiales) {
		this.pilotosOficiales = pilotosOficiales;
	}

	public void setPilotosProbadores(ArrayList<Piloto> pilotosProbadores) {
		this.pilotosProbadores = pilotosProbadores;
	}

	public void setCoches(Coche[] coches) {
		this.coches = coches;
	}

	/*public void setListaCompetidores(ArrayList<PilotoCoche> listaCompetidores) {
		this.listaCompetidores = listaCompetidores;
	}
	
	
	//comprueba si existe piloto en la escudería
	public boolean existePiloto(Piloto piloto){
		return (getPilotosOficiales().contains(piloto) || getPilotosProbadores().contains(piloto));
	}*/
	
	/*método que permite a la escudería fichar un piloto. Comprueba si la escudería está capacitada para hacerlo, y en el caso
	de que el piloto a fichar pertenezca a una escudería, lo sacará de ella.
	Si el piloto no pertenece a una escuderia este parámetro será null*/
	public boolean ficharPiloto(Piloto piloto,int tipoPiloto,Escuderia escuderia){
		boolean res=false;
		//si se trata de fichar un piloto oficial
		if(tipoPiloto==PILOTO_OFICIAL){
                    PilotoOficial pil=new PilotoOficial(piloto);
			//compruebo que se pueda realizar el fichaje: preupuesto y piltos contratados
			if(comprobarPresupuesto(pil.getSueldo())){
				hacerPago(pil.getSueldo());
				pilotosOficiales.add(pil);
				res=true;
			}
		}else if (tipoPiloto==PILOTO_PROBADOR){
                     PilotoProbador pil=new PilotoProbador(piloto);
			//compruebo que se pueda realizar el fichaje: preupuesto y piltos contratados
			if(comprobarPresupuesto(pil.getSueldo())){
				hacerPago(pil.getSueldo());
				pilotosProbadores.add(pil);
				res=true;
			}
		}
		//en el caso de que el piloto perteneciera a alguna escudería lo saco de ella
		/*if (res==true && escuderia!=null){
			escuderia.despedirPiloto((Piloto)piloto);
		}*/
		return res;
	}
	
	//método que permite intercambiar piloto con otra escudería. Comprobación de diferencia entre pilotos <10%
	public boolean cambiarPiloto(Piloto pilotoA,Piloto pilotoB, Escuderia escuderia){
		boolean res=false;
		double a=pilotoA.getSueldo();
		double b=pilotoB.getSueldo();
		//compruebo que la diferencia de valor de los pilotos no supera el 10 %
		if (a>b){
			if((a-b)*100/a<=10){
				res=true;
			}
		
		}else if(a<b){
			if((b-a)*100/b<=10){
				res=true;
			}
		}else{
			res=true;
		}
		
		//hago el intercambio si la valoración ha sido positiva
		if(res){
			//en el caso de que mi piloto sea un piloto oficial lo sustituyo por el de la otra escudería
			if (pilotoA instanceof PilotoOficial){
                                //convierto a B en piloto oficial
                                PilotoOficial pB=new PilotoOficial(pilotoB);
                                deshacerEquipo(pB);
				pilotosOficiales.set(pilotosOficiales.indexOf(pilotoA), pB);
				//en el caso de que mi piloto sea un piloto probador lo sustituyo por el de la otra escudería
			}else{
                                //convierto a B en pilotoProbador
                                PilotoProbador pB=new PilotoProbador(pilotoB);
				pilotosProbadores.set(pilotosProbadores.indexOf(pilotoA), pB);
			}
                        
                        int index=-1;
			//sustituyo el piloto de la otra escuderia
			if (pilotoB instanceof PilotoOficial){
                                //convierto al piloto A en piloto Oficial
                                 PilotoOficial pA=new PilotoOficial(pilotoA);
                                //averiguo  que indice del listado de pilotos se encuentra el pilotoB
                                for(int i=0;i<escuderia.getPilotosOficiales().size();i++){
                                    if(escuderia.getPilotosOficiales().get(i).getNombre().equals(pilotoB.getNombre())&&escuderia.getPilotosOficiales().get(i).getApellidos().equals(pilotoB.getApellidos())){
                                        index=i;
                                        break;
                                    }
                                }
                                //deshago el equipo si existia uno donde estaba este piloto
                                escuderia.deshacerEquipo(pA);
				escuderia.getPilotosOficiales().set(index, pA);
				//en el caso de que mi piloto sea un piloto probador lo sustituyo por el de la otra escudería
			}else{
                            //convierto al piloto A en piloto Probador
                            PilotoProbador pA=new PilotoProbador(pilotoA);
                            //averiguo ene que indice del listado de pilotos se encuentra el pilotoB
                                for(int i=0;i<escuderia.getPilotosProbadores().size();i++){
                                    if(escuderia.getPilotosProbadores().get(i).getNombre().equals(pilotoB.getNombre())&&escuderia.getPilotosProbadores().get(i).getApellidos().equals(pilotoB.getApellidos())){
                                        index=i;
                                        break;
                                    }
                                }
				escuderia.getPilotosProbadores().set(index, pA);
			}
						
		}
		
		
		return res;
	}
	
        /*
         * utilizado por el método despedir piloto. método para deshacer un equipo de competición en el caso de que el piloto que se depide pasado como parámetro
         * se encuentre en el equipo. 
         */
	private void deshacerEquipo(Piloto piloto){
            //compruebo si está en un equipo de competición y si está borro el equipo
            for(int i=0;i<listaCompetidores.size();i++){
               if(piloto.getNombre().equals(listaCompetidores.get(i).getPiloto().getNombre()) 
                        && piloto.getApellidos().equals(listaCompetidores.get(i).getPiloto().getApellidos())){
                 listaCompetidores.remove(i);
               }
            }
        }
        
        /*
         * método para deshacer un equipo de competición.
         */
        public void deshacerEquipo(PilotoCoche equipo){
            
            //compruebo si está en un equipo de competición y si está borro el equipo
            /*for(int i=0;i<getListaCompetidores().size();i++){
                //las comparo mediante el modelo de cohce nombre de pilot
                String s1=getListaCompetidores().get(i).getCoche().getModelo()+getListaCompetidores().get(i).getPiloto().getNombre();
                String s2=equipo.getCoche().getModelo()+equipo.getPiloto().getNombre();
                if(s1.equals(s2)){
                    //la borro
                    getListaCompetidores().remove(i);
                }
            }*/
            getListaCompetidores().remove(equipo);
        }
	/*método que hace que un piloto deje la escudería, si es un piloto oficial el que deja la escudería devolvera 0;
	si es un piloto oficial devolverá 1, y si no se ha podido realizar devuelve -1;*/
	public int despedirPiloto(Piloto piloto) {
		int res=-1;
                if(piloto instanceof PilotoOficial){
                    for (int i=0;i<pilotosOficiales.size();i++){
                        if(pilotosOficiales.get(i).getNombre().equals(piloto.getNombre()) && pilotosOficiales.get(i).getApellidos().equals(piloto.getApellidos())){
                            //compruebo si está en un equipo de competición y si está borro el equipo
                            deshacerEquipo(piloto);
                            pilotosOficiales.remove(i);
                            res=PILOTO_OFICIAL;
                            break;
                        }
                    }
                }else{
                    for (int i=0;i<pilotosProbadores.size();i++){
                        if(pilotosProbadores.get(i).getNombre().equals(piloto.getNombre()) && pilotosProbadores.get(i).getApellidos().equals(piloto.getApellidos())){
                            pilotosProbadores.remove(i);
                            res=PILOTO_PROBADOR;
                            break;
                        }
                    }
                }
		return res;
	}
	
	//hacer pago
	public boolean hacerPago(double pago){
		boolean res=false;
		if (comprobarPresupuesto(pago)){
			presupuesto=presupuesto-pago;
			res=true;
		}
		return res;
	}
        
	//comprueba el presupuesto de la escudería
	private boolean comprobarPresupuesto(double pago) {
		return presupuesto>=pago;
	}
	
	public boolean darVueltaEntrenamiento(Circuito circuito, Piloto piloto, Coche coche){
		boolean res =false;
		//antes de entrenar se intenta pagar el canon del circuito. Si este no se puede asumir no se enetrenará
		res=hacerPago(circuito.getCanon());
		//si hay dinero para hacer le entrenamiento se dará una vuelta y mejoraran las cualidades del coche y piloto
		if (res){
                    //dependiendo del tipo de piloto que entrene la mejora será diferente
                    if (piloto instanceof PilotoOficial){
                        ((PilotoOficial)piloto).entrenar();
                    }else{
                        ((PilotoProbador)piloto).entrenar();
                    }
                    
                    //mejora el coche
                    coche.darVueltaEntrenamiento();
		}
		return res;
	}


	
        public String EquipoToString(){
            String equipo="";
            for (int i=0;i<this.listaCompetidores.size();i++){
                    equipo+="Coche "+listaCompetidores.get(i).getCoche().getModelo()+"-"+listaCompetidores.get(i).getPiloto().getNombre();
                if(i<this.listaCompetidores.size()-1){
                    equipo+="; ";
                }else{
                   equipo+="\n"; 
                } 
		
            }
            return equipo;
        }
        
    @Override
    
        public String toString(){
		String pilotosOf="";
		String pilotosPro="";
                String cocheStr="";
		for (int i=0;i<pilotosProbadores.size();i++){
			pilotosPro="Pilototo Probador"+i+ ": "+pilotosProbadores.get(i).getNombre()+" "+pilotosProbadores.get(i).getApellidos()+"\n";
		}
		for (int i=0;i<pilotosOficiales.size();i++){
			pilotosOf="Pilototo oficial"+i+ ": "+pilotosOficiales.get(i).getNombre()+" "+pilotosOficiales.get(i).getApellidos()+"\n";
		}
                /*for (int i=0;i< coches.length;i++){
                    if (!"".equals(coches[i].getModelo()))
                        cocheStr="Coche " + i +": "+ coches[i].getModelo()+"\n"; 
                }*/
		return "Propietario: " + propietario + "\n"+
				"Nombre: " + nombre+ "\n"+
				"País: " + pais + "\n"+
				"Año Fundación: "+ anyoFundacion + "\n"+
				"Presupuesto: "+ presupuesto + "\n"+
                                "Directivos: "+ directivos + "\n"+
				 pilotosOf+ pilotosPro + EquipoToString()+cocheStr;
	}
    
    //método que crea una lista de competidores aleatoria en el caso de que no haya equipos asignados
    public void crearListaAutomCompetidores() {
        
        //tendrá en cuenta el número de pilotos oficiales y coches que tiene la escudería
        
        int nPil=pilotosOficiales.size();
        int nCoches=0;
        for(int i=0;i<coches.length;i++){
            if(coches[i]!=null){
                nCoches+=1;
            }
        }
        //se crean los equipos de forma aletoria
        if(nPil>0&& nCoches>0){
            int nEquipos=0;
            //controlo que no hay el mismo número de pilotos que de coches
            if(nPil>=nCoches){
                nEquipos=nCoches;
            }else{
                nEquipos=nPil;
            }
            for (int i=0;i<nEquipos;i++){
                PilotoCoche pC=new PilotoCoche(pilotosOficiales.get(i), coches[i]);
                listaCompetidores.add(pC);
            }
        }
    }
    //inicializa la puntuación de los pilotos y la escuderia al empezar el mundial
    public void empezarMundial(){
        puntos=0;
        for (int i=0;i<pilotosOficiales.size();i++){
            pilotosOficiales.get(i).setPuntos(0);
        }
    }

}
